package mth.masterimp;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;

import mth.masterimp.DataRepresentator;

public class AlphaCalculator {

	/*
	 * Diese Klasse stellt die zentrale Steuerung des Programmablaufs bereit.
	 * Von hier aus werden die einzelnen Hauptmethoden der verbundenen Klassen aufgerufen.
	 * Hier werden die Parameter verwaltet und der Dateiname für die Ausgabedatei erweitert.
	 * 
	 * Achtung: Da es sich um eine prototypische Implementierung handelt, ist weder die
	 * vollständige Fehlerbehandlung noch ein UI enthalten. Es existieren durchaus noch
	 * offene Fehler, die die Lösung der Probleme zwar beeinflussen, allerdings nicht
	 * wesentlich zur Verminderung der Qualität beitragen.
	 */
	private int k;
	private String technique;
	private String file;
	private DataRepresentator dr;
	private Constraints constraint;
	AlphaWeightsCalculation awc;
	private int queries;
	private String distanceMeasure;
	private boolean appendRandom;
	
	AlphaCalculator (int knew, String fil, String distM, String tech, String q, String appRand) {
		technique = tech;
		k = knew;
		file = fil;
		dr=new DataRepresentator(fil,distM,knew); //right here the Data will load
		appendRandom = (appRand.equals("1"))?true:false;
		queries=Integer.parseInt(q);
		constraint=new Constraints(dr,technique, queries, appendRandom);
		distanceMeasure=distM;
	}
	
	/********************************************************
	 **********P U B L I C **********************************
	 **********************S E C T I O N*********************
	 ********************************************************/
	
	public int getK() {
		return k;
	}
	
	public String getFile() {
		return file;
	}
	
	public void setK(int knew) {
		k = knew;
	}
	
	public void setFile (String fil) {
		file = fil;
	}
	
	public void printAll(String outputfile) {
		java.util.Date d = new Date();
		outputfile+=String.valueOf(d.getTime())+"_"+distanceMeasure;
		outputfile+="_qall_"+constraint.getAmountOfAllQueries() + "_pairs_" +
		constraint.getAmountOfConstraints() + "_nquest_" + constraint.getAmountOfNegativeQueries();
		dr.print(outputfile); 
		constraint.printCQGc(outputfile);
		awc.print(outputfile);
//		printParameter(outputfile);
	}
	
	private void printParameter(String ofile) {
		String outputString="";
		outputString+="Input File: "+ file + "\n"
				+"Sammeltechnik: ";
		outputString+=(technique.equals("B"))?"Basu":"me";
		outputString+="\n"
				+"Anzahl der Cluster: " + k + "\n"
				+"Anzahl vorgegebener Fragen: " + queries + "\n"
				+"Distanzmass: " + distanceMeasure + "\n"
				+"zusätzliche Abfragen (nur eigener Ansatz): " + appendRandom + "\n"
				+"Output File: " + ofile;
		
		try {
			FileWriter fw = new  FileWriter(ofile+"_alphaCalculator_props", false);
			fw.write(outputString);
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * ATTENTION!!!!
	 * the special value columns (id, label, cluster) MUST BE the
	 * last few columns, best way is to hold the named order
	 * @param args
	 * -f file
	 * -k k
	 * -m constraint collection Method "B" || "m"
	 * -q amount of queries to ask
	 * -d distance measure
	 * -o output file
	 * -a append random queries --> only own approach
	 * -q queries: the available amount of allowed queries
	 */
	public static void main(String[] args){
		String file="";
		String k="";
		String collectionMethod="";
		String queries="";
		String distMeasure="";
		String outputFile="";
		String appRand="";
		
		if (args!=null && args.length!=0) {
			for (int a=0; a<args.length; a++) {
				if (args[a].equals("-f")) {
					file=args[++a];
				} else if (args[a].equals("-k")) {
					k=args[++a];
				} else if (args[a].equals("-m")) {
					collectionMethod=args[++a];
				} else if (args[a].equals("-q")) {
					queries=args[++a];
				} else if (args[a].equals("-d")) {
					distMeasure=args[++a];
				} else if (args[a].equals("-o")) {
					outputFile=args[++a];
				} else if (args[a].equals("-r")) {
					appRand=args[++a];
				}
			}
		}
		if (file.equals("")) {
			System.out.println("No input File set.");
			return;
		}
		if (k.equals(""))
			k=String.valueOf(3);
		if (distMeasure.equals(""))
			distMeasure="Euclidian";
		if (collectionMethod.equals("") || (!collectionMethod.equals("B") && !collectionMethod.equals("m")))
			collectionMethod="B";//default: B
		if (queries.equals(""))
			queries="-1";//default: -1
		if (appRand.equals(""))
			appRand="0";//default 0
		if (outputFile.equals(""))
			outputFile="/output/result";
		
		//Es ist notwendig, die Distanzmaße aus dem RapidMiner-Log zu übersetzen,
		//da die Initialisierung in WhiBo andere Namen fordert.
		if (distMeasure.equals("EuclideanDistance")) {
			distMeasure="Euclidian";
		} else if (distMeasure.equals("CamberraDistance")) {
			distMeasure="Camberra";
		} else if (distMeasure.equals("ChebychevDistance")) {
			distMeasure="Chebychev";
		} else if (distMeasure.equals("CorrelationSimilarity")) {
			distMeasure="CorrelationNumerical";
		} else if (distMeasure.equals("DiceSimilarity")) {
			distMeasure="DiceNumerical";
		} else if (distMeasure.equals("DynamicTimeWarpingDistance")) {
			distMeasure="DTWNumerical";
		} else if (distMeasure.equals("InnerProductSimilarity")) {
			distMeasure="InnerProduct";
		} else if (distMeasure.equals("JaccardSimilarity")) {
			distMeasure="JaccardNumerical";
		} else if (distMeasure.equals("MaxProductSimilarity")) {
			distMeasure="MaxProduct";
		} else if (distMeasure.equals("OverlapSimilarity")) {
			distMeasure="OverlapNumerical";
		} else if (distMeasure.equals("ManhattanDistance")) {
			distMeasure="CityBlok";
		}
		
		AlphaCalculator alpha = new AlphaCalculator(Integer.parseInt(k), file, distMeasure , collectionMethod, queries, appRand);
		alpha.constraint.buildAllConstraints();
		alpha.awc= new AlphaWeightsCalculation(alpha.constraint.getNeighborhoods(), alpha.constraint.getPairs(), alpha.constraint.getPairCount());
		alpha.awc.calculateWeights();
		alpha.awc.useWeights();
		alpha.printAll(outputFile);
	}

}
